package com.github.common.extend.demo.config.filetask.excel;

import com.github.common.extend.demo.config.filetask.FileTaskCallback;
import com.github.common.extend.demo.config.filetask.FileTaskParam;
import com.github.common.extend.demo.util.iterator.partition.fixed.LocalDateTimePartitionParam;
import javax.servlet.http.HttpServletResponse;
import java.time.temporal.TemporalUnit;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;

/**
 * excel下载任务管理
 * @author wangjj7
 * @date 2023/8/29
 * @description
 */
public interface ExcelTaskDownloader {

    /**
     * 生成excel并输出到http响应
     * @param headType
     * @param iterator
     * @param fileName
     * @param response
     * @param <T>
     */
    <T> void writeThenDownload(Class<T> headType, Iterator<T> iterator, String fileName ,HttpServletResponse response);

    /**
     * 提交文件任务，将数据写入excel，成功后将生成的excel输出到http响应
     * @param fileTaskParam 任务定义
     * @param headType excel头类型
     * @param iterator 待写入元素迭代器
     * @param response http响应
     * @param <T>
     */
    <T> void submitWriteTaskThenDownload(FileTaskParam fileTaskParam, Class<T> headType,
                                         Iterator<T> iterator, HttpServletResponse response);

    /**
     * 异步提交文件任务，将数据写入excel，成功后将生成的excel输出到http响应
     * @param fileTaskParam 任务定义
     * @param headType excel头类型
     * @param iterator 待写入元素迭代器
     * @param response http响应
     * @param fileTaskCallback 文件任务回调
     * @param <T>
     */
    <T> void asyncSubmitWriteTaskThenDownload(FileTaskParam fileTaskParam, Class<T> headType,
                                              Iterator<T> iterator, HttpServletResponse response,
                                              FileTaskCallback fileTaskCallback);

    /**
     * 重载
     * @see #asyncSubmitWriteTaskThenDownload(FileTaskParam, Class, Iterator, HttpServletResponse, FileTaskCallback)
     */
    default <T> void asyncSubmitWriteTaskThenDownload(FileTaskParam fileTaskParam, Class<T> headType,
                                                      Iterator<T> iterator, HttpServletResponse response)
    {
        asyncSubmitWriteTaskThenDownload(fileTaskParam, headType, iterator, response ,null);
    }

    /**
     * 提交文件任务，根据时间分片的规则分批将数据写入excel，成功后将生成的excel输出到http响应
     * 如果结果集很大且查询参数带时间范围，可以将时间拆分成一个个小时间分片后通过此方法分批写入
     * @param fileTaskParam 任务定义
     * @param query 查询条件（注意如果想要支持重复任务共享，重写hashcode()和equals()方法）
     * @param headType excel头类型
     * @param partitionSize 时间分片大小
     * @param partitionInterval 时间分片间隔
     * @param unit 分片单位
     * @param asc true:升序，false:降序
     * @param queryFunction 分片查询函数
     * @param response http响应
     * @param <T>
     * @param <P>
     */
    <T ,P extends LocalDateTimePartitionParam<P>> void submitWriteByTimePartitionTaskThenDownload(
            FileTaskParam fileTaskParam, P query, Class<T> headType,
            int partitionSize, int partitionInterval, TemporalUnit unit, boolean asc,
            Function<P, List<T>> queryFunction, HttpServletResponse response);

    /**
     * 异步提交文件任务，根据时间分片的规则分批将数据写入excel，成功后将生成的excel输出到http响应
     * 如果结果集很大且查询参数带时间范围，可以将时间拆分成一个个小时间分片后通过此方法分批写入
     * @param fileTaskParam 任务定义
     * @param query 查询条件（注意如果想要支持重复任务共享，重写hashcode()和equals()方法）
     * @param headType excel头类型
     * @param partitionSize 时间分片大小
     * @param partitionInterval 时间分片间隔
     * @param unit 分片单位
     * @param asc true:升序，false:降序
     * @param queryFunction 分片查询函数
     * @param response http响应
     * @param fileTaskCallback 文件任务执行回调
     * @param <T>
     * @param <P>
     */
    <T ,P extends LocalDateTimePartitionParam<P>> void asyncSubmitWriteByTimePartitionTaskThenDownload(
            FileTaskParam fileTaskParam, P query, Class<T> headType,
            int partitionSize , int partitionInterval, TemporalUnit unit, boolean asc,
            Function<P, List<T>> queryFunction, HttpServletResponse response,
            FileTaskCallback fileTaskCallback);

    /**
     * 重载
     * @see #asyncSubmitWriteByTimePartitionTaskThenDownload(FileTaskParam, LocalDateTimePartitionParam, Class, int, int, TemporalUnit, boolean, Function, HttpServletResponse ,FileTaskCallback)
     */
    default <T ,P extends LocalDateTimePartitionParam<P>> void asyncSubmitWriteByTimePartitionTaskThenDownload(
            FileTaskParam fileTaskParam, P query, Class<T> headType,
            int partitionSize , int partitionInterval, TemporalUnit unit, boolean asc,
            Function<P, List<T>> queryFunction, HttpServletResponse response)
    {
        asyncSubmitWriteByTimePartitionTaskThenDownload(fileTaskParam, query, headType, partitionSize,
                partitionInterval, unit, asc, queryFunction, response ,null);
    }

}
